package com.lingnan.gatewayserver.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Calendar;
import java.util.Map;

public class JWTUtil {
    private static final String TOKENKey = "79135jkl";

    /**
     * 生成token
     * @param map
     * @return 返回token
     */
    public static String getToken(Map<String, String> map) {
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.DATE, 7);//7天过期

        //添加payload
        JWTCreator.Builder builder = JWT.create();
        map.forEach((k, v) -> {
            builder.withClaim(k, v);
        });

        builder.withExpiresAt(instance.getTime());//设置令牌过期时间
        //生成并返回token
        String token = builder.sign(Algorithm.HMAC256(TOKENKey)).toString();

        // 添加打印代码用于调试
        System.out.println("Generated Token: " + token);
        System.out.println("Token Length: " + token.length());
        System.out.println("Token Parts: " + String.join(", ", token.split("\\.")));

        return token;
    }

    /**
     * 验证token
     *
     * @param token
     * @return
     */
    public static boolean verify(String token) {
        // 移除Bearer前缀（如果存在）
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7); // "Bearer ".length() = 7
        }

        // 添加打印代码用于调试
        System.out.println("Verifying Token: " + token);
        if (token != null) {
            System.out.println("Token Length: " + token.length());
            System.out.println("Token Format Valid: " + isValidTokenFormat(token));
        }

        if (token == null || token.isEmpty()) {
            System.out.println("Token is null or empty");
            return false;
        }

        try {
            JWT.require(Algorithm.HMAC256(TOKENKey))
                    .build()
                    .verify(token);
            System.out.println("Token verified successfully");
            return true;
        } catch (JWTDecodeException e) {
            // token 格式错误
            System.err.println("JWT Decode Exception: " + e.getMessage());
            return false;
        } catch (Exception e) {
            // 其他错误（如签名错误、过期等）
            System.err.println("JWT Verify Exception: " + e.getMessage());
            return false;
        }
    }

    /**
     * 获取token中payload
     * @param token
     * * @return
     */
    public static DecodedJWT getTokenInfo(String token) {
        // 移除Bearer前缀（如果存在）
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7); // "Bearer ".length() = 7
        }

        // 添加打印代码用于调试
        System.out.println("Getting Token Info: " + token);
        if (token != null) {
            System.out.println("Token Length: " + token.length());
            System.out.println("Token Format Valid: " + isValidTokenFormat(token));
        }

        if (token == null || token.isEmpty()) {
            System.out.println("Token is null or empty");
            return null;
        }

        try {
            DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC256(TOKENKey))
                    .build()
                    .verify(token);
            System.out.println("Token decoded successfully");
            System.out.println("Subject: " + decodedJWT.getSubject());
            System.out.println("Expires At: " + decodedJWT.getExpiresAt());
            return decodedJWT;
        } catch (JWTDecodeException e) {
            System.err.println("JWT Decode Exception: " + e.getMessage());
            return null;
        } catch (Exception e) {
            System.err.println("JWT Verify Exception: " + e.getMessage());
            return null;
        }
    }

    /**
     * 验证token格式是否正确
     * @param token
     * @return
     */
    private static boolean isValidTokenFormat(String token) {
        if (token == null || token.isEmpty()) {
            return false;
        }

        String[] parts = token.split("\\.");
        boolean valid = parts.length == 3;
        System.out.println("Token part count: " + parts.length + ", valid: " + valid);

        if (valid) {
            for (int i = 0; i < parts.length; i++) {
                System.out.println("Part " + (i+1) + " length: " + parts[i].length());
            }
        }

        return valid;
    }
}
